# Copyright 2022 Flant JSC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

{!{- $pullRequestContext := coll.Dict "pullRequestRefField" "needs.pull_request_info.outputs.ref" -}!}
{!{- $ctx := coll.Merge $pullRequestContext . -}!}

# Run validation script on every push to dev branches.
#
# Validation scripts require  PR title, PR description and diff.
# Title and description are available when PR is already created.
# Diff content is fetched using 'diff_url' field in payload when PR is available.
# If PR is not created, 'compare' field is used to get diff between base branch and dev branch.
#
# See also scripts/validation_run.sh.
#

name: Validations
on:
  pull_request_target:
     types:
      - opened
      - synchronize

# Cancel in-progress jobs for the same PR (pull_request_target event) or for the same branch (push event).
concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
  cancel-in-progress: true

jobs:
  close_dependabot_prs_for_forks:
    name: Autoclose Dependabot PRs for forks
    runs-on: ubuntu-latest
    if: ${{ github.actor == 'dependabot[bot]' && github.repository != 'deckhouse/deckhouse' }}
    env:
      ENABLE_DEPENDABOT_IN_FORKS: ${{ secrets.ENABLE_DEPENDABOT_IN_FORKS }}
    steps:
      - name: Close PR
        uses: {!{ index (ds "actions") "actions/github-script" }!}
        with:
          github-token: ${{ secrets.BOATSWAIN_GITHUB_TOKEN }}
          script: |
            // Keep PR if explicitly enabled.
            const {ENABLE_DEPENDABOT_IN_FORKS} = process.env;
            const prNum = context.payload.pull_request.number;
            const repo = context.payload.repository.full_name;
            if (ENABLE_DEPENDABOT_IN_FORKS === 'true') {
              core.info(`Secret ENABLE_DEPENDABOT_IN_FORKS is 'true', proceed with validation for PR#${prNUM} in repo ${repo}.`);
              return
            }
            core.info(`Secret ENABLE_DEPENDABOT_IN_FORKS is not 'true', close PR#${prNum} in repo ${repo}.`);
            return await github.rest.pulls.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: prNum,
              state: 'closed'
            });

{!{ tmpl.Exec "pull_request_info_job" $ctx | strings.Indent 2 }!}

  # Get pull request info for validation scripts.
  # Push event has no pull request information, so retrieve it with Rest API.
  discover:
    name: Prepare input for validation scripts
    needs:
      - pull_request_info
    runs-on: ubuntu-latest
    outputs:
      run_no_cyrillic: ${{ steps.check_labels.outputs.run_no_cyrillic }}
      label_no_cyrillic: ${{ steps.check_labels.outputs.label_no_cyrillic }}
      run_doc_changes: ${{ steps.check_labels.outputs.run_doc_changes }}
      label_doc_changes: ${{ steps.check_labels.outputs.label_doc_changes }}
      run_copyright: ${{ steps.check_labels.outputs.run_copyright }}
      label_copyright: ${{ steps.check_labels.outputs.label_copyright }}
      run_markdown: ${{ steps.check_labels.outputs.run_markdown }}
      label_markdown: ${{ steps.check_labels.outputs.label_markdown }}
      run_grafana_dashboard: ${{ steps.check_labels.outputs.run_grafana_dashboard }}
      label_grafana_dashboard: ${{ steps.check_labels.outputs.label_grafana_dashboard }}
      run_release_requirements: ${{ steps.check_labels.outputs.run_release_requirements }}
      label_release_requirements: ${{ steps.check_labels.outputs.label_release_requirements }}
    steps:
{!{ tmpl.Exec "checkout_step" $ctx | strings.Indent 6 }!}
      - id: check_labels
        name: Check labels on push
        uses: {!{ index (ds "actions") "actions/github-script" }!}
        env:
          PR_LABELS: ${{ needs.pull_request_info.outputs.labels }}
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const labels = JSON.parse(process.env.PR_LABELS)

            const ci = require('./.github/scripts/js/ci');
            return ci.checkValidationLabels({ core, labels });

      - name: Download diff for pull request
        env:
          DIFF_URL: ${{ needs.pull_request_info.outputs.diff_url }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          ./.github/scripts/validation_run.sh --download-only ./pr.diff

      - name: Upload diff as artifact
        uses: {!{ index (ds "actions") "actions/upload-artifact" }!}
        with:
          name: pr_diff
          path: pr.diff

  no_cyrillic_validation:
    name: No Cyrillic Validation
    env:
      VALIDATE_TITLE: ${{ needs.pull_request_info.outputs.pr_title }}
      VALIDATE_DESCRIPTION: ${{ needs.pull_request_info.outputs.pr_description }}
{!{ tmpl.Exec "validation_template" (slice $ctx "no_cyrillic") | strings.Indent 4 }!}

  doc_validation:
    name: Documentation Validation
{!{ tmpl.Exec "validation_template" (slice $ctx "doc_changes") | strings.Indent 4 }!}

  copyright_validation:
    name: Copyright Validation
{!{ tmpl.Exec "validation_template" (slice $ctx "copyright") | strings.Indent 4 }!}

  grafana_dashboard_validation:
    name: Grafana Dashboard Validation
{!{ tmpl.Exec "validation_template" (slice $ctx "grafana_dashboard") | strings.Indent 4 }!}

  markdown_linter:
    name: Markdown Linter
{!{ tmpl.Exec "linter_template" (slice $ctx "markdown") | strings.Indent 4 }!}

  release_requirements_validation:
    name: Release Requirements Validation
{!{ tmpl.Exec "validation_template" (slice $ctx "release_requirements") | strings.Indent 4 -}!}

{!{/* Template for validation jobs. */}!}
{!{ define "validation_template" }!}
{!{- $ctx := index . 0 -}!}
{!{- $type := index . 1 }!}
needs:
  - discover
  - pull_request_info
if: needs.discover.outputs.run_{!{ $type }!} == 'true'
runs-on: ubuntu-latest
steps:
  {!{ tmpl.Exec "checkout_step" $ctx | strings.Indent 2 }!}

  - name: Restore diff artifact
    uses: {!{ index (ds "actions") "actions/download-artifact" }!}
    with:
      name: pr_diff

  - name: Run check
    env:
      DIFF_PATH: ./pr.diff
      SKIP_LABEL_NAME: ${{ needs.discover.outputs.label_{!{ $type }!} }}
    run: |
      ./.github/scripts/validation_run.sh ./testing/validate_{!{ $type }!}.sh
{!{- end -}!}

{!{/* Template for linter jobs. */}!}
{!{ define "linter_template" }!}
{!{- $ctx := index . 0 -}!}
{!{- $type := index . 1 }!}
needs:
  - discover
  - pull_request_info
if: needs.discover.outputs.run_{!{ $type }!} == 'true'
runs-on: ubuntu-latest
steps:
  {!{ tmpl.Exec "checkout_step" $ctx | strings.Indent 2 }!}

  - name: Restore diff artifact
    uses: {!{ index (ds "actions") "actions/download-artifact" }!}
    with:
      name: pr_diff

  - name: Run linter
    env:
      DIFF_PATH: ./pr.diff
      SKIP_LABEL_NAME: ${{ needs.discover.outputs.label_{!{ $type }!} }}
    run: |
      make lint-{!{ $type }!}
{!{- end -}!}
